package zdream.rockchronicle.core.graphics;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.Array;

import java.util.Objects;

import zdream.control.graphics.IPainter;
import zdream.control.region.Gate;
import zdream.control.region.Room;
import zdream.control.world.LevelCamera;
import zdream.control.world.MHookType;
import zdream.control.world.Ticker;
import zdream.rockchronicle.RockChronicle;

/**
 * 渲染 TMX 的
 * 
 * @author Zdream
 * @since 0.0.1
 * @date 2022-05-28
 */
public class RegionPainter implements IPainter {
	public final RockChronicle app;

	/**
	 * 渲染当前 Tiled 地图的, 因此会常驻且不会被回收
	 */
	public OrthogonalTiledMapRenderer mainRender;

	/**
	 * 地图的渲染列表, 渲染其它区域的. 当出现跨 Region 的渲染时启用.
	 * 暂时先不考虑 TODO
	 */
	public Array<MapRendererEntry> renders = new Array<>();

	@Override
	public void draw(Ticker ticker) {
		if (mainRender.getMap() == null) {
			return;
		}

		fixMapRender(app.graphics.camera);
		mainRender.render();

		for (int i = 0; i < renders.size; i++) {
			renders.get(i).render.render();
		}
	}

	float windowsWidth = 25;
	float windowsHeight = 14;
	float scaleX = 2;
	float scaleY = 2;

	private void fixMapRender(OrthographicCamera camera) {
		// 当前区域
		final LevelCamera levelCamera = app.levels.camera;
		Room curRoom = app.levels.currentRoom;

		Rectangle fakeBounds = mainRender.getViewBounds();
		fakeBounds.setX(levelCamera.view.x + curRoom.offsetX); // 单位也是块不是像素
		fakeBounds.setY(levelCamera.view.y + curRoom.offsetY);
		fakeBounds.setWidth(levelCamera.view.width);
		fakeBounds.setHeight(levelCamera.view.height);

		// camera 是以 room 为坐标系的
		// mainRender 是以 region 为坐标系的, 所以还需要偏移
		mainRender.getBatch().setProjectionMatrix(camera.combined);
		mainRender.getBatch().getProjectionMatrix().translate(-curRoom.offsetX, -curRoom.offsetY, 0);

		// 其它区域
//		for (int i = 0; i < renders.size; i++) {
//			MapRendererEntry entry = renders.get(i);
//			OrthogonalTiledMapRenderer render = entry.render;
//			Gate gate = entry.gate;
//
//			render.setView(camera);
//			Rectangle viewBounds0 = render.getViewBounds();
//			viewBounds0.setX(viewBounds0.x + curRoom.offsetx + gate.offsetXOfRegion);
//			viewBounds0.setY(viewBounds0.y + curRoom.offsety + gate.offsetYOfRegion);
//
//			render.getBatch().getProjectionMatrix()
//				.translate(dx - gate.offsetXOfRegion,
//						dy - gate.offsetYOfRegion,
//						0);
//		}
	}

	@Override
	public int zIndex() {
		return 0;
	}

	static class MapRendererEntry {
		OrthogonalTiledMapRenderer render;
		Gate gate;
	}

	public RegionPainter(RockChronicle app) {
		this.app = Objects.requireNonNull(app);
		mainRender = new OrthogonalTiledMapRenderer(null, 1f / 24);
		app.putSubscriber(this::onRoomUpdated, MHookType.ROOM_UPDATED);
	}

	private void onRoomUpdated() {
		Room room = app.levels.currentRoom;
		if (room != null) {
			mainRender.setMap(app.storage.currentRegion.tmx);
		}
	}

	@Override
	public void dispose() {
		mainRender.dispose();
	}
}
